﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using NetJavap;
using NetJavap.JVM;
using NetJavap.AttributeInfos;
using System.IO;
using System.Diagnostics;

namespace Test
{
    class Program
    {
        static void Main(string[] args)
        {
            for (int i = 0; i < 1; i++)
            {
                
                JVMCodeRunner.OnNativeInvokeNeed += runner_OnNativeInvokeNeed;
                JavaObject stringObj = Utils.CreateStringInstance("aaasda");
                JavaClass entry = JVMClassLoader.LoadClass("Main");
                CodeAttributeInfo codeInfo = entry.Methods[2].GetAttribute<CodeAttributeInfo>();
                JVMCodeRunner runner = new JVMCodeRunner(codeInfo);
                while (!runner.ExecuteSetp()) ;
            }
        }

        static void runner_OnNativeInvokeNeed(object sender, NativeInvokeEventArgs e)
        {
            switch (e.Method.Name.Value)
            {
                case "sin":
                    e.ReturnValue = Math.Sin((double)e.Parameters[0]);
                    break;
                case "registerNatives":
                    break;
                case "getPrimitiveClass":
                    break;
                case "floatToRawIntBits":
                    e.ReturnValue = ((Single)e.Parameters[0]).GetHashCode();
                    break;
                case "doubleToRawLongBits":
                    e.ReturnValue = (Int64)((Double)e.Parameters[0]).GetHashCode();
                    break;
                case "nanoTime":
                    e.ReturnValue = (Int64)(Process.GetCurrentProcess().TotalProcessorTime.Ticks);
                    break;
                case "currentTimeMillis":
                    e.ReturnValue = DateTime.UtcNow.Ticks;
                    break;
                case "identityHashCode":
                    Object obj = e.Parameters[0];
                    e.ReturnValue = obj.GetHashCode();
                    break;
                case "getClassLoader0":
                    e.ReturnValue = null;
                    break;
                case "desiredAssertionStatus0":
                    e.ReturnValue = 0;
                    break;
                case "arraycopy":
                    ArrayJavaObject src = e.Parameters[0] as ArrayJavaObject;
                    Int32 srcPos = (Int32)e.Parameters[1];
                    ArrayJavaObject dest = e.Parameters[2] as ArrayJavaObject;
                    Int32 destPos = (Int32)e.Parameters[3];
                    Int32 length = (Int32)e.Parameters[4];
                    Array.Copy(src.Elements, srcPos, dest.Elements, destPos, length);
                    break;
                default:
                    Single s = 1.0f;
                    int hash = s.GetHashCode();
                    throw new NotImplementedException("未实现底层调用：" + e.Method.FullName);
                    
            }
        }
    }
}
